home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Technical Documentation / Misc. Standards / BinHex 4.0 (Text) / BinHex 4.0 Specs (Text)
Encoding:
Text File  |  1993-02-27  |  8.7 KB  |  224 lines  |  [TEXT/MSWD]

  1. BinHex 4.0 Definition by Peter N Lewis, Aug 1991.
  2.  
  3. For a long time BinHex 4.0 has been the standard for ASCII encoding of 
  4. Macintosh files.  To my knowledge, there has never been a full 
  5. definition of this format.  Info-Mac had an informal definition of the 
  6. format, but this lacked a description of the CRC calculation, as well as 
  7. being vague in some areas.  Hopefully this document will fully define 
  8. the BinHex 4.0 standard, and allow more programmers to fully implement 
  9. it.  Note, however, that this definition is how I see the BinHex 
  10. standard, and since I had no part whatsoever in defining it initially, 
  11. this document can have no real claim to being the one true definition.  
  12. If anyone feels that I have not got the facts straight, or that it is 
  13. ambiguous in any details, please contact me at the address at the bottom 
  14. of this document.
  15.  
  16. Format:
  17.  
  18. It is necessary to distinguish between the encoding format and decoding 
  19. format since we wish to allow all decoders to read all versions of the 
  20. BinHex format, while trying to reduce the variation in encoding.
  21.  
  22. All numbers are decimal unless they have the format 0xFF, in which case 
  23. they are hex.
  24.  
  25.     <tab> is a tab, character value 9.
  26.     <lf>  is a linefeed, character value 10.
  27.     <cr> is a carriage return, character value 13.
  28.     <spc> is a space, character value 32.
  29.     <return> means to the encoder:
  30.     The sequence <cr> <lf>.  Either (but not both) may be omitted.
  31.     Use whatever is appropriate for your system (<cr> for Mac,
  32.     <lf> for Unix, <cr><lf> for MS-DOS).
  33.  
  34.     <return> means to the decoder:
  35.     Any sequence of zero or more of <cr>, <lf>, <tab>, <spc>.
  36.     (The <tab> and <spc> are required because some old programs
  37.     produced these characters).
  38.     For example, <cr> <tab> <lf> <spc> <lf> <cr> would be perfectly
  39.     acceptable.
  40.  
  41. A hqx file begins with a description which should be ignored by the 
  42. decoder (and generally left blank by encoding software).  The hqx file 
  43. proper consists of the sequence:
  44.  
  45. <start-of-line>(This<spc>file<spc>must<spc>be<spc>converted<spc>with
  46. <spc>BinHex<spc>4.0)<return>:<hqx-file>:<return>
  47.  
  48. When encoding, DO NOT mess with the "(This file..." string.  There are a 
  49. large number of automated programs that use it, and they may stumble 
  50. over anything other than this exact string.
  51.  
  52. When decoding, you should only check the string up to "with BinHex", 
  53. then skip until either a <cr> or <lf>, then skip <return> characters, 
  54. and check for the colon.  Also, be careful with the <start-of-line>, 
  55. this can be either a <return> character, or the start of the file.  Some 
  56. old programs produced an extra exclamation mark (!) immediately before 
  57. the final colon (:).  When decoding, after all data is read, skip any 
  58. <return> characters, and then allow a single optional exclamation mark 
  59. (and then skip <returns> again) before checking for the terminating 
  60. colon.  Don't check for a <return> after the colon.
  61.  
  62. <hqx-file> is a sequence of 6-bit encoded characters.
  63.  
  64. When encoding, a <return> should be inserted after every 64 characters.  
  65. The first character should follow immediately after the first colon 
  66. (without a <return>), and the first line should be 64 characters long, 
  67. (unless its also the last line obviously) including the colon.  The  
  68. final colon should go on the same line as the last character and there  
  69. should be a return after it.  Thus, the final line must be between 2 and  
  70. 65 (inclusive) characters long.
  71.  
  72. When decoding, lines of any length should be accepted, and <return> 
  73. characters should be ignored everywhere (before and after the first 
  74. colon, between any two hqx characters, and before the trailing colon.
  75.  
  76. This string defines the valid characters, in order:
  77.  
  78. !"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr
  79. (ie, ! is 0, " is 1, ..., r is 63).
  80.  
  81. When decoding, any character other that those 64 and the <return> 
  82. characters indicates an error and the user should be notified of such.
  83.  
  84. The format also supports run length encoding, where the character to be 
  85. repeated is followed by a 0x90 byte then the repeat count.  For example, 
  86. FF9004 means repeat 0xFF 4 times.  The special case of a repeat count of 
  87. zero means it's not a run, but a literal 0x90.  2B9000 => 2B90.
  88.  
  89. *** Note: the 9000 can be followed by a run, which means to repeat the 
  90. 0x90 (not the character previous to that).  That is, 2B90009005 means a 
  91. 2B9090909090.
  92.  
  93. Before encoding into RLE, 6-bits (or after if decoding), the file is 
  94. formatted into a header, data fork, and resource fork.  All three are 
  95. terminated with a two byte CRC.
  96.  
  97. The header consists of a one byte name length, then the file name, then 
  98. a one byte 0x00.  The rest of the header is 20 bytes long, and contains 
  99. the file type, creator, file flags, data and resource lengths, and the 
  100. two byte CRC value for the header.
  101.  
  102. When encoding, the flags should be copied directly from the Finder Info.  
  103. When decoding, the OnDesk, Invisible, and Initted flags should be 
  104. cleared.
  105.  
  106. Also, when decoding, the file name should be validated for the given OS.  
  107. For example, a Mac program should replace a full stop (.) at the front 
  108. of a file name with a bullet (option-8), and should replace colons (:) 
  109. with dashes (-) and, if running under A/UX, slashes should be replaced 
  110. by dashes (-).
  111.  
  112. The data fork and resource fork contents follow in that order.  If a 
  113. fork is empty, there will be no bytes of contents and the checksum will 
  114. be two bytes of zero.
  115.  
  116. So the decoded data between the first and last colon (:) looks like:
  117.  
  118.      1       n       4    4    2    4    4   2    (length)
  119.     +-+---------+-+----+----+----+----+----+--+
  120.     |n| name... |0|TYPE|AUTH|FLAG|DLEN|RLEN|HC|   (contents)
  121.     +-+---------+-+----+----+----+----+----+--+
  122.  
  123.             DLEN             2    (length)
  124.     +--------------------------------------+--+
  125.     |    DATA FORK               |DC|    (contents)
  126.     +--------------------------------------+--+
  127.  
  128.             RLEN             2    (length)
  129.     +--------------------------------------+--+
  130.     |    RESOURCE FORK               |RC|    (contents)
  131.     +--------------------------------------+--+
  132.  
  133. CRCs:
  134.  
  135. BinHex 4.0 uses a 16-bit CRC with a 0x1021 seed.  The general algorithm 
  136. is to take data 1 bit at a time and process it through the following:
  137.  
  138. 1)  Take the old CRC (use 0x0000 if there is no previous CRC)
  139.     and shift it to the left by 1.
  140.  
  141. 2)  Put the new data bit in the least significant position (right bit).
  142.  
  143. 3)  If the bit shifted out in (1) was a 1 then xor the CRC with 0x1021.
  144.  
  145. 4)  Loop back to (1) until all the data has been processed.
  146.  
  147. Or in pseudo pascal:
  148.  
  149. var crc:integer; { init to zero at the beginning of each of the three 
  150. forks }
  151.  
  152. procedure CalcCRC (v: integer);  { 0<=v<=255 }
  153.     var
  154.         temp: boolean;
  155.         i: integer;
  156. begin
  157.     for i := 1 to 8 do begin
  158.         temp := (crc AND 0x8000) <> 0;
  159.         crc := (crc << 1) OR (v >> 7);
  160.         if temp then
  161.             crc := crc XOR 0x1021;
  162.         v := (v << 1) AND 0xFF;
  163.     end;
  164. end;
  165.  
  166. When encoding, include two bytes of 0x00 where the CRC should be, and 
  167. use them in the calculation of the CRC before writing it to the file.  
  168. Similarly, when decoding, calculate the CRC over all the bytes in the 
  169. fork (header, data, or resource) except the last two CRC bytes, then 
  170. continue the CRC calculation with two 0x00 bytes, then compare it to the 
  171. CRC stored in the file.
  172.  
  173. Parts:
  174.  
  175. If you wish to support segmented files in the same way that 
  176. comp.binaries.mac files are segmented,  use the following line to note 
  177. the end of a hqx part:
  178.  
  179.     <return>--- end of part NN ---<return>
  180.  
  181. Note: When decoding, it is only necessary to check for "<return>--- end 
  182. of part".
  183.  
  184. Recommence decoding (either later in this file, or in the next file) 
  185. when  you encounter the line:
  186.  
  187.     <return>---<return>
  188.  
  189. Note:  In this case, when decoding, demand either a <cr> or <lf> both 
  190. immediately before, and immediately after the ---.  It is unfortunate 
  191. that this sequence is in fact valid hqx data, but there should not be 
  192. any  problems with this.
  193.  
  194. Sources to refer to:
  195.  
  196. FTP from sumex-aim.stanford.edu
  197.     A file called hqx-format.txt which I can no longer find.
  198.     info-mac/unix/xbin
  199.     info-mac/unix/mcvert
  200.     info-mac/source/pascal/dehqx
  201.  
  202. Author: 
  203.  
  204. Peter N Lewis <Lewis_P@cc.curtin.edu.au>
  205. 10 Earlston way,
  206. Booragoon 6154 WA,
  207. AUSTRALIA
  208.  
  209. Contributors:
  210.  
  211. Roland Mansson <Roland.Mansson@LDC.lu.se>
  212. Steve Dorner <dorner@pequod.cso.uiuc.edu>
  213. Sak Wathanasin <sw@network-analysis-ltd.co.uk>
  214. Dave Green <daveg@Apple.com>
  215. Tom Coradeschi <tcora@PICA.ARMY.MIL>
  216. Howard Haruo Fukuda <physi-hf@garnet.berkeley.edu>
  217. Michael Fort <mfort@ub.d.umn.edu>
  218. Dave Johnson <ddj%brown@csnet-relay.ARPA>
  219.  
  220. Note: I attempted to contact all these people, but only a few replied.  
  221. Some of them may not wish to be associated with this document, and 
  222. certainly they should not be seen as endorsing it in any way.  
  223. Obviously, any errors in this document are my own!
  224.